package com.liu.activiti.controller;

import com.liu.activiti.exception.CustomException;
import com.liu.activiti.pojo.activiti.CustomPeddingTaskRep;
import com.liu.activiti.pojo.activiti.CustomProcessInstance;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.util.CollectionUtil;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工作流接口
 */
@Slf4j
@RestController
@RequestMapping("/activiti")
public class ActivitiController {

    @Autowired
    public TaskService taskService;
    @Autowired
    public RuntimeService runtimeService;
    @Autowired
    public HistoryService historyService;
    @Autowired
    public RepositoryService repositoryService;

    /**
     * 初始化实例
     */
    @RequestMapping("/init")
    @ResponseBody
    public Deployment init(String fileName) {
//        String fileName = "bpmn/qingjia.bpmn20.xml";
        Deployment deployment = this.repositoryService.createDeployment()
                .addClasspathResource(fileName)
                .name("请假流程测试")
                .deploy();
        log.info("流程部署名称：" + deployment.getName());
        return deployment;
    }

    /**
     * 开始流程
     *
     * @param key 流程key 默认是流程图的id
     * @param businessKey 业务id
     */
    @RequestMapping("/start")
    @ResponseBody
    public CustomProcessInstance start(String key, String businessKey, Integer qingjiadate, String kz) {
        //流转中的参数
        Map<String, Object> variables = new HashMap<>();
        variables.put("kzUserId", kz);
        variables.put("qingjiadate", qingjiadate);

        ProcessInstance processInstance = this.runtimeService.startProcessInstanceByKey(key, businessKey, variables);
        log.info("流程实例：" + processInstance);
        CustomProcessInstance customProcessInstance = new CustomProcessInstance();
        BeanUtils.copyProperties(processInstance, customProcessInstance);
        log.info("启动流程实例-startActiviti end, instance:{}, customProcessInstance:{}", processInstance, customProcessInstance);
        return customProcessInstance;
    }

    /**
     * 查询正在进行中的任务
     *
     * @param businessKey 业务id
     */
    @RequestMapping("/peddingTaskList")
    @ResponseBody
    public ArrayList<CustomPeddingTaskRep> peddingTaskList(String businessKey, String assignee, String processInstanceId) {
        //查询接口
        TaskQuery taskQuery = taskService.createTaskQuery();

        //任务指定用户人
        if (StringUtils.isNotBlank(assignee)) {
            taskQuery.taskAssignee(assignee);
        }
        //业务标识
        if (StringUtils.isNotBlank(businessKey)) {
            taskQuery.processInstanceBusinessKey(businessKey);
        }
        //流程实例ID
        if (StringUtils.isNotBlank(processInstanceId)) {
            taskQuery.processInstanceId(processInstanceId);
        }

        List<Task> list = taskQuery.list();
        log.info("查询原生流程返回结果list:{}", list);
        final ArrayList<CustomPeddingTaskRep> taskReps = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)) {
            for (Task task : list) {
                final CustomPeddingTaskRep customPeddingTaskRep = new CustomPeddingTaskRep();
                customPeddingTaskRep.setTaskId(task.getId());
                customPeddingTaskRep.setTaskName(task.getName());
                customPeddingTaskRep.setTaskAssiginee(task.getAssignee());
                customPeddingTaskRep.setExecutionId(task.getExecutionId());
                customPeddingTaskRep.setProcessDefinitionId(task.getProcessDefinitionId());
                customPeddingTaskRep.setProcessInstanceId(task.getProcessInstanceId());
                customPeddingTaskRep.setDfinitionKey(task.getTaskDefinitionKey());
                taskReps.add(customPeddingTaskRep);
            }
        }
        return taskReps;
    }

    /**
     * 任务完成
     *
     * @param businessKey 业务id
     * @param processInstanceId 流程实例ID
     * @param assignee 用户人
     */
    @RequestMapping("/completeTask")
    @ResponseBody
    public CustomPeddingTaskRep completeTask(String businessKey, String assignee, String processInstanceId) {
        //查询接口
        TaskQuery taskQuery = taskService.createTaskQuery();
        //任务指定用户人
        if (StringUtils.isNotBlank(assignee)) {
            taskQuery.taskAssignee(assignee);
        }
        //业务标识
        if (StringUtils.isNotBlank(businessKey)) {
            taskQuery.processInstanceBusinessKey(businessKey);
        }
        //流程实例ID
        if (StringUtils.isNotBlank(processInstanceId)) {
            taskQuery.processInstanceId(processInstanceId);
        }
        List<Task> list = taskQuery.list();
        if (list.isEmpty()) {
            throw new CustomException("当前专家没有可完成的任务！");
        }
        //理论上 绑定业务id的情况下 只有一个代办任务
        Task task = list.get(0);
        //完成任务
        Map<String, Object> variables = new HashMap<>();
        taskService.complete(task.getId(), variables);
        CustomPeddingTaskRep customPeddingTaskRep = new CustomPeddingTaskRep();
        customPeddingTaskRep.setTaskId(task.getId());
        customPeddingTaskRep.setTaskName(task.getName());
        customPeddingTaskRep.setTaskAssiginee(task.getAssignee());
        customPeddingTaskRep.setExecutionId(task.getExecutionId());
        customPeddingTaskRep.setProcessDefinitionId(task.getProcessDefinitionId());
        customPeddingTaskRep.setProcessInstanceId(task.getProcessInstanceId());
        return customPeddingTaskRep;
    }


}
